typedef struct {
    int* arr;
    int top;    //栈顶(元素个数)
    int capacity;
    int min;
} MinStack;

/** initialize your data structure here. */

MinStack* minStackCreate() {
    MinStack* ms = (MinStack*)malloc(sizeof(MinStack));
    if(NULL == ms){
        assert(0);
        return NULL;
    }
    ms->capacity = 3;    //初始容量
    ms->arr = (int*)malloc(sizeof(int) * ms->capacity);
    if(NULL == ms->arr){
        assert(0);
        return NULL;
    }
    ms->top = 0;
    ms->min = INT_MAX;
    return ms;
}

//检查栈容量 并扩容
static void CheckCapacity(MinStack* obj)
{
    assert(obj);
    if(obj->top == obj->capacity){    //栈容量已满
        int newcapacity = obj->capacity * 2;
        int* temp = (int*)malloc(sizeof(int) * newcapacity);  //申请新空间
        if(NULL == temp){
            assert(0);
            return;
        }
        //拷贝元素
        memcpy(temp, obj->arr,  sizeof(int) * obj->top);   
        free(obj->arr);
        obj->arr = temp;     //使用新空间
        obj->capacity = newcapacity;

    }    
}

int minStackTop(MinStack* obj) {
    assert(obj);
    return obj->arr[obj->top-1];
}

void minStackPush(MinStack* obj, int x) {
    assert(obj);
    CheckCapacity(obj);
    obj->arr[obj->top] = x;
    if(obj->min > x){
        obj->min = x;
    }
    (obj->top)++;
}

void minStackPop(MinStack* obj) {
    assert(obj);
    if(obj->top){    //栈不为空
        obj->top--;    

        if (obj->top) {
            obj->min = minStackTop(obj);
        } 
        else {
            obj->min = INT_MAX;
        }
        for (int i = 0; i < obj->top; i++) {
            if (obj->arr[i] < obj->min) {
                obj->min = obj->arr[i];
            }
        }
    }
    
}

int minStackMin(MinStack* obj) {
    assert(obj);
    return obj->min;
}

void minStackFree(MinStack* obj) {
    assert(obj);
    if(obj->arr){
        free(obj->arr);
        obj->arr = NULL;
        obj->capacity = 0;
        obj->top = 0;
        obj->min = INT_MAX;
    }
}


/**
 * YourinStack struct will be instantiated and called as such:
 * MinStack* obj = minStackCreate();
 * minStackPush(obj, x);
 
 * minStackPop(obj);
 
 * int param_3 = minStackTop(obj);
 
 * int param_4 = minStackMin(obj);
 
 * minStackFree(obj);
*/